Introduction à R

Aujourd’hui on apprend ce qu’est le logiciel d’analyse statistique R.

Les materiaux sont adaptés des ressources excellents de CSBQ:

https://r.qcbs.ca/workshop01/book-fr/index.html

https://r.qcbs.ca/workshop02/book-fr/index.html

https://r.qcbs.ca/workshop03/book-fr/index.html

Objectifs

1. Comprendre ce que sont R et RStudio

2. Manipuler et créer les objets dans R

3. Installer et utiliser les packages R

4. Manipuler les tableus de données dans R

5. Créer des visualisation de données avec le package ggplot

Qu’est-ce que R et pourquoi l’utiliser?

  • C’est gratuit!
  • C’est compatible avec Mac, Linux, et Windows, ce qui rend le partage de codes R facile.
  • R peut créer des tableaux, produire des graphiques et faire des analyses statistiques, le tout au sein du même logiciel. Avec R, il devient inutile d’utiliser plus d’un logiciel pour la gestion de vos données. Tout est possible avec un seul logiciel !
  • De plus en plus de scientifiques utilisent R chaque année. Ses capacités sont en augmentation constante et vont continuer dans cette direction au fil des années. Cela signifie également qu’il y a une grande communauté en ligne qui peut vous donner un coup de main lorsque vous rencontrez un problème dans R.

La raison la plus importante pour moi:

C’est répétable et reproductible!

Ça veut dire qu’on peut utiliser notre code pour répéter nos analyses et on arrive à la même solution. On peut egalement partager notre code pour que les autres puissent répéter les analyses.

Pourquoi est-ce que c’est utile? Imagine tu travailles dans un laboratoire qui realise un service de protéomique. Pour chaque groupe d’échantillons tu dois préparer des statistiques et des figures et tu reçevois 100 échantillons par semaine!

Avec R, c’est facile d’ajouter des données et refaire une analyse! On peut également automatiser les analyses. (Exemple)

Installation

Il faut installer le logiciel R et le logiciel RStudio. RStudio n’est pas strictement obligatoire, mais l’experience d’apprentisage et de l’utilisation est plus agréable avec RStudio.

Pour obtenir le logiciel R: http://www.r-project.org/

  • cliquez sur « Download »
  • sélectionner un site miroir (préférablement un situé près de vous)
  • choisir votre plateforme (OS X, Windows ou Linux)
  • téléchargez le fichier et lancez-le afin de compléter l’installation

Pour obtenir R Studio: https://posit.co/download/rstudio-desktop/

Les bases

Ouvrez RStudio et explorez.

On y trouve plusieurs onglets et fenêtres. La console est pour executer le code. Tapez et appuyer sur “enter” pour que le code soit exécuté dans la console.

Exemple: Faites des calculs

1 + 1
## [1] 2
2 - 1
## [1] 1
2 * 2
## [1] 4
8 / 2
## [1] 4
2 ^ 3
## [1] 8

Normalement, on n’utilise pas la console pour taper et executer le code, parce que ce n’est pas enregistré. À la place, on utilise les scripts pour écrire et enregistrer le code.

Ouvrez un nouveau R script

Dans le script on peut écrire le code et l’executer en appuyant sur Alt + Enter (ou Cmd + Enter). Les lignes qui debutent par # sont ignorées, donc c’est très utile pour faire des commentaires! Laissant les commentaires pour annoter votre code est extrêmement important!

Les objets

R est un langage de programmation par objet (object-oriented programming language). Ça signifie qu’on peut allouer un nom à des valeurs qu’on a créées afin de les enregistrer dans un espace de travail. Un objet est composé de trois parties : 1) une valeur d’intérêt, 2) un identifiant et 3) l’opérateur d’assignation.

  1. La valeur d’intérêt peut être à peu près de n’importe quelle nature : un nombre, le résultat d’un calcul, une chaîne de caractères, un tableau de données, un graphique ou une fonction.
  2. L’identifiant est le nom qui est assigné à la valeur d’intérêt. Lorsqu’on veut faire référence à cette valeur, il suffit simplement de taper son nom à la console et R va afficher cette valeur. Les identifiants peuvent seulement inclure des lettres, des chiffres, des points et des traits de soulignement (underscore). Ils doivent toujours débuter par une lettre.
  3. L’opérateur d’assignation ressemble à une flèche (<-) et est utilisé afin de lier la valeur d’intérêt à son identifiant.

Exemple:

x <- 3 * (14 / 2)

Dans cet exemple, 3 * (14 / 2) est la valeur qu’on souhaite enregistrer en tant qu’objet. L’identifiant "x" est assigné à cette valeur. En tapant x à la console ou en executant dans le script, R retourne la valeur du calcul:

x
## [1] 21

Faites attention: R fait la différence entre les lettres miniscules et majuscules:

X
## Error in eval(expr, envir, enclos): object 'X' not found

Bonnes pratiques du code R

Nom:

  • Essayez d’avoir des noms courts et explicites pour vos variables. Nommer une variable var n’est pas très instructif.
  • Utilisez un trait de soulignement _ pour séparer les mots d’un nom ou essayez d’être constant!
  • Évitez les noms d’objets de fonction qui existe dans R (e.g. c ou table)

Espace:

  • Ajoutez des espaces autour de tous les opérateurs (=, +, -, <-, etc.) pour rendre le code plus lisible

Types de structures de données en R

Le logiciel R est un outil très puissant pour l’analyse des données. Les données existent sous plusieurs formes, mais peuvent être regroupées en catégories distinctes. R classifie les données selon la nature des valeurs contenues dans un objet. La figure suivante illustre les types de données couramment rencontrés dans R.

Types de structures de données en R: le vecteur

Le premier type d’objet est le vecteur. C’est un des objets les plus communs dans R. Un vecteur est une entité constituée d’une liste de valeurs semblables. Toutes les valeurs d’un vecteur doivent avoir le même mode (ou classe). Les principaux modes dans R sont numérique, caractère et logique. Les vecteurs numériques sont seulement composés de nombres. Les vecteurs de caractères sont généralement composés de chaînes de caractères ou d’un mélange de chaînes de caractères et de valeurs numériques et logiques. Il est absolument nécessaire d’utiliser les guillemets " " afin de délimiter les chaînes de caractères. Les vecteurs logiques sont composés des mots TRUE et FALSE seulement.

Regardons maintenant comment générer différents types de vecteurs (i.e. de différents modes).

#Créez un vecteur numérique avec la fonction c (qui signifie combiner ou concaténer).
num_vecteur <- c(1, 4, 3, 98, 32, -76, -4)
num_vecteur
## [1]   1   4   3  98  32 -76  -4
#Créez un vecteur de caractères. N’oubliez pas les guillemets !
car_vecteur <- c("bleu", "rouge", "vert")
car_vecteur
## [1] "bleu"  "rouge" "vert"
#Créez un vecteur logique ou booléen. N’utilisez pas les guillemets sinon R va considérer les éléments
#comme des chaînes de caractères.
bool_vecteur <- c(TRUE, TRUE, FALSE)
bool_vecteur
## [1]  TRUE  TRUE FALSE
#C’est aussi possible d’utiliser les abréviations pour les vecteurs logiques.
bool_vecteur2 <- c(T, T, F)
bool_vecteur2
## [1]  TRUE  TRUE FALSE

Pourquoi est-ce que les vecteurs sont utiles? les vecteurs peuvent être utilisés dans des calculs. La seule différence est que, lorsqu’un vecteur a plus d’un élément, l’opération est appliquée à tous les éléments du vecteur. L’exemple suivant clarifie ceci.

#Créez deux vecteurs numériques.
x <- 1:5
# Le symbole '':'', lorsqu’utilisé avec des chiffres, est l’opérateur de séquence.
# Ça indique à R de créer une série qui augmente de 1.
# C’est équivalent à écrire x <- c(1, 2, 3, 4, 5)
# Une autre façon équivalente est : x <- c(1:5).

y <- 6

# Faisons la somme des deux vecteurs.
# 6 est ajouté à tous les éléments du vecteur x.
x + y
## [1]  7  8  9 10 11
# Multiplions x par y.
x * y
## [1]  6 12 18 24 30

Types de structures de données en R: le data frame

Un autre type d’objet couramment utilisé en biologie, écologie et anthropologie est le data frame (c-à-d. tableau de données). Un data frame est un groupe de vecteurs de la même longueur (i.e. avec le même nombre d’éléments). Les variables sont toujours représentées en colonnes et les observations, cas, individus, sites ou répétitions sont toujours représentés en lignes. Un data frame peut être composé de plusieurs modes, mais une colonne doit toujours contenir le même mode. C’est sous ce format que la plupart des données écologiques sont enregistrées. L’exemple suivant présente un jeu de données fictif représentant quatre sites où le pH du sol et le nombre d’espèces ont été mesurés. On y trouve également une colonne de traitement (fertilisé ou non). Regardons plus en détail comment créer un tel tableau de données.

site_id pH_sol num_sp traitement
A1.01 5.6 17 Fertilisé
A1.02 7.3 23 Fertilisé
B1.01 4.1 15 Non Fertilisé
B1.02 6.0 17 Non Fertilisé

N. B. Les noms des colonnes et leur contenu n’ont ni accent, ni d’espace, ni caractères spéciaux puisque R préfère une seule suite de caractères comme titre. Ainsi, num_sp représente bien ‘Nombre d’espèces’, mais R préfère la forme ‘num_sp’. Il en va de même pour le contenu du tableau (pas ‘Fertilisé’, mais bien ‘Fert’).

# On commence par créer les vecteurs.
site_id <- c("A1.01", "A1.02", "B1.01", "B1.02") # l'identifiant du site
pH_sol <- c(5.6, 7.3, 4.1, 6.0) #la mesure du pH du sol à chaque site
num_sp <- c(17, 23, 15, 7) #le nombre d'espèces observées
traitement <- c("Fert", "Fert", "Non_fert", "Non_fert") #traitement appliqué

# On peut grouper tous ces vecteurs en un data frame avec la fonction data.frame().
mon_df <- data.frame(site_id, pH_sol, num_sp, traitement)

# On l’affiche à la console!
mon_df
##   site_id pH_sol num_sp traitement
## 1   A1.01    5.6     17       Fert
## 2   A1.02    7.3     23       Fert
## 3   B1.01    4.1     15   Non_fert
## 4   B1.02    6.0      7   Non_fert

Les autres types d’objets pour stocker des données qu’on retrouve dans R sont les matrices, les tableaux (i.e. array en anglais) et les listes. Une matrice est très similaire à un data frame à l’exception que toutes les cellules de la matrice doivent être du même mode. Un array est similaire à une matrice, mais peut avoir plus de deux dimensions. Les arrays sont surtout utilisés pour des calculs avancés tels que des simulations numériques et des tests de permutations. Une liste est un groupement de plusieurs types d’objets différents. Par exemple, une liste pourrait comprendre un vecteur, un tableau de données et une matrice au sein du même objet.

Indexer des objets dans R


Indexer un vecteur

Lorsqu’on tape le nom d’un objet dans la console, R retourne l’objet en entier. Par contre, ce n’est pas pratique si l’objet est, par exemple, une énorme base de données avec des millions de lignes. Ça peut rapidement devenir difficile d’identifier des éléments précis d’un objet. R nous permet d’extraire certaines parties d’un objet en indexant ce dernier. Il suffit de spécifier la position des valeurs à l’intérieur d’un objet qu’on souhaite extraire à l’aide des crochets [ ]. Le code suivant illustre le concept d’indexation des vecteurs.

# Créons tout d’abord un vecteur numérique et un vecteur de caractères.
# Ce n’est pas nécessaire de faire cette étape si vous l’avez déjà fait dans un exercice précédent.
impair <- c(1, 3, 5, 7, 9)

# Extrayons le deuxième élément du vecteur numérique.
impair[2]
## [1] 3
# Extrayons les 2ème et 4ème éléments du vecteur numérique.
impair[c(2, 4)]
## [1] 3 7
# Extrayons tous les éléments du vecteur numérique sauf les deux premières.
impair[c(-1, -2)]
## [1] 5 7 9
# Si nous sélectionnons une position qui n'existe pas dans le vecteur numérique.
impair[c(1,6)]
## [1]  1 NA

Il n’y a pas de sixième valeur dans ce vecteur, donc R retourne une valeur nulle (i.e. NA). NA signifie ‘Not available’.

# Nous pouvons également utiliser des conditions pour sélectionner des valeurs.
impair[impair > 4]
## [1] 5 7 9
# Nous pouvons procéder de même sur les vecteurs de caractère
# Extraire tous les éléments correspondant exactement à « bleu » du vecteur de caractères.
# Prenez note de l’utilisation du double signe d’égalité ==.
car_vecteur[car_vecteur == "rouge"]
## [1] "rouge"
#Pour chaque élément du vecteur `car_vecteur`, R vérifie si cet élément est exactement égal à « bleu » ou non et retourne une réponse (TRUE ou FALSE)
car_vecteur == "rouge"
## [1] FALSE  TRUE FALSE

Indexer un data frame

L’indexation des data frames est similaire à celle des vecteurs, mais il est généralement nécessaire de spécifier deux dimensions : le numéro de ligne et de colonne. Pour ce faire, la syntaxe dans R est :

data frame[numéro de ligne, numéro de colonne].

Voici quelques exemples d’indexation de data frames. Prenez note que les quatre premières opérations sont également valides pour les matrices.

# Réutilisons le data frame créé précédemment (mon_df)
# Extrayons la première ligne du data frame.
mon_df[1, ]
##   site_id pH_sol num_sp traitement
## 1   A1.01    5.6     17       Fert
# Extrayons la troisième colonne du data frame.
mon_df[, 3]
## [1] 17 23 15  7
# Notez qu'un index vide sélectionne toutes les valeurs

# Extrayons le deuxième élément de la quatrième colonne du data frame.
mon_df[2, 4]
## [1] "Fert"
# Extrayons les lignes 2 et 4 du data frame.
mon_df[c(2,4), ]
##   site_id pH_sol num_sp traitement
## 2   A1.02    7.3     23       Fert
## 4   B1.02    6.0      7   Non_fert
# Extrayons la colonne « site_id » en référant directement à son nom.
# Le signe de dollar ($) permet une telle opération !
mon_df$site_id
## [1] "A1.01" "A1.02" "B1.01" "B1.02"
# Extrayons la deuxième valeur de la colonne « site_id »
mon_df$site_id[2]
## [1] "A1.02"
# Extrayons les variables « site_id » et « pH_sol ».
mon_df[,c("site_id","pH_sol")]
##   site_id pH_sol
## 1   A1.01    5.6
## 2   A1.02    7.3
## 3   B1.01    4.1
## 4   B1.02    6.0

Installer et utiliser les librairies R

Les packages (bibliothèques pour être rigoureux) sont des regroupements de fonctions et de jeux de données partageant un thème similaire, e.g. statistiques, analyse spatiale, visualisation…

Tout le monde peut développer des packages et les rendre disponibles aux autres utilisateurs de R.

Les packages sont généralement disponibles via le Comprehensive R Archive Network (CRAN) http://cran.r-project.org/web/packages/.

Actuellement, plus de 18000 packages sont disponibles librement.

Pour installer des packages dans R, il suffit d’utiliser la fonction install.packages()

Il est nécessaire d’installer un package une seule fois, même si des mises à jours régulières sont recommandées. Cependant, pour utiliser une fonction se trouvant au sein d’un package, il ne suffit pas de simplement installer le package. Il faut également utiliser la fonction library() à chaque début de session R pour “charger” le package.

Installons les packages dont on a besoin aujourd’hui:

install.packages(c("ggplot2", "tidyr", "dplyr", "palmerpenguins", "lubridate"))

Charger, explorer et enregistrer des données

Vous avez appris comment créer un dataframe “à la main” mais normalement, ce n’est pas pratique. Fréquemment, les données sont dans les fichiers comme excel ou csv puis c’est plus facile de les importer directement.

Répertoire de travail

Vous devez indiquer à R le répertoire où se trouvent les fichiers de données afin de les charger. Vous pouvez voir quel répertoire R utilise avec la fonction getwd()”

getwd()  # Cette commande vous indique le répertoire dans lequel vous vous trouvez.
## [1] "/Users/mjaniak/Documents/UdeM/R"

Lorsque vous chargez un script, R définit le répertoire de travail comme étant le dossier qui contient le script.

Afin de spécifier le chemin d’accès du répertoire avec la fonction setwd(), utilisez le “/” pour séparer les dossiers, sous-dossiers et noms de fichiers. Vous pouvez aussi cliquer sur session / Définir le répertoire / Choisir le répertoire.

Afficher le contenu du répertoire de travail

La fonction dir() affiche le contenu du répertoire de travail.

dir() # Cette commande vous indique le contenu du répertoire dans lequel vous vous trouvez.

Vous pouvez vérifier:

  • Si le fichier que vous voulez ouvrir se trouve dans le répertoire de travail ou non
  • L’orthographe du nom du fichier (e.g. ‘monfichier.csv’ au lieu de ‘MonFichier.csv’)

Importer un jeu de données

Utilisez la fonction read.csv() pour importer des données provenant d’un fichier .csv dans R.

CO2<-read.csv("CO2_good.csv", header = TRUE)
# Cette commande crée un objet nommé CO2 en chargeant les données
# du fichier nommé "CO2_good.csv".

Cette commande spécifie que vous créez un objet nommé “CO2” en lisant un fichier .csv nommé “CO2_good.csv”.

L’argument header permet de spécifier si la première ligne du fichier contient le nom des colonnes. Inscrire header=TRUE indique à R que la première ligne du tableau contient les noms des colonnes.

Explorer le jeu de données

Le jeu de données “CO2” contient des mesures répétées d’absorption de CO2 prises sur six plantes du Québec et six plantes du Mississippi à différentes concentrations de CO2 ambiant. La moitié des plantes de chaque région a subi un traitement de refroidissement la veille du début de l’expérience.

Rappelez-vous de la section “Indexer un data frame”. Utilisez les operations afin d’explorer CO2.

Changer les noms de variables

On peut changer le nom de variables (colonnes) dans R.

# afficher les noms des colonnes présents dans le jeu de données:
colnames(CO2)
## [1] "Plant"     "Type"      "Treatment" "conc"      "uptake"
# changer des noms anglais à des noms français:
colnames(CO2) <- c("Plante", "Categorie", "Traitement", "conc", "absortion")

Créer des nouvelles variables

On peut facilement créer et produire des nouvelles variables. Par exemple, la fonction paste() permet la concaténation de chaînes de caractères et de variables.

# Créer un ID unique pour les échantillons avec la fonction
# ''paste()'' Consultez ?paste et ?paste0 N'oubliez pas
# d'utiliser '' pour les chaînes de caractères
CO2$uniqueID <- paste0(CO2$Plante, "_", CO2$Categorie,
    "_", CO2$Traitement)

# Observer les résultats
CO2

On peut aussi créer des nouvelles variables à partir de chiffres et d’opérations mathématiques!

# Standardizer la variable 'absortion' en valeurs relatives
CO2$absortionRel = CO2$absortion/max(CO2$absortion)

# Observer les résultats
head(CO2$absortionRel)
## [1] 0.3516484 0.6681319 0.7648352 0.8175824 0.7758242 0.8615385

Explorer les données

Pour faire une première exploration de données, on peut rapidement calculer des statistiques de base avec la fonction summary().

summary(CO2)
##      Plante         Categorie       Traitement      conc        absortion    
##  Qn1    : 7   Quebec     :42   nonchilled:42   Min.   :  95   Min.   : 7.70  
##  Qn2    : 7   Mississippi:42   chilled   :42   1st Qu.: 175   1st Qu.:17.90  
##  Qn3    : 7                                    Median : 350   Median :28.30  
##  Qc1    : 7                                    Mean   : 435   Mean   :27.21  
##  Qc3    : 7                                    3rd Qu.: 675   3rd Qu.:37.12  
##  Qc2    : 7                                    Max.   :1000   Max.   :45.50  
##  (Other):42                                                                  
##   absortionRel   
##  Min.   :0.1692  
##  1st Qu.:0.3934  
##  Median :0.6220  
##  Mean   :0.5981  
##  3rd Qu.:0.8159  
##  Max.   :1.0000  
## 

Plusieurs fonctions intégrées à R vous permettent d’obtenir de l’information supplémentaire sur vos données. Les fonctions mean(), sd(), hist(), et print() sont couramment utilisées.

# Calculer la moyenne et l'écart type des données dans la colonne "conc" de l'objet CO2
meanConc<-mean(CO2$conc) # Calcule la moyenne de la colonne "conc" de l'objet "CO2"
sdConc<-sd(CO2$conc) # Calcule l'écart-type de la colonne "conc"

# print() sort une valeure dans la console R 
print(paste("la concentration moyenne est:", meanConc)) 
## [1] "la concentration moyenne est: 435"
print(paste("l'écart type de la concentration est:", sdConc))
## [1] "l'écart type de la concentration est: 295.924119222056"
# Produisez un histogramme to explore the distribution of "uptake"
hist(CO2$absortion)

# Augmenter le nombre de classes pour mieux observer la distribution
hist(CO2$absortion, breaks = 40)


Manipuler les données avec le Tidyverse

Pourquoi réorganiser ses données?

La réorganisation permet de modifier la structure des données tout en préservant l’information contenue dans le jeu de données. Plusieurs fonctions dans R exigent ou fonctionnent mieux avec une structure de données qui n’est pas nécessairement propice à la lecture par l’oeil humain.

En comparaison à l’agrégation, où plusieurs cellules sont regroupées pour créer un nouveau jeu de données (e.g. tableau des moyennes de plusieurs variables), la réorganisation maintient le même nombre de cellules. Le paquet tidyr permet de réorganiser nos jeu de données dans un format idéal pour nos tâches en aval, et ce à l’aide d’une syntaxe simple et logique.

tidyr est un paquet qui réorganise la structure de jeux de données.

  • Convertir de format large en format long à l’aide de pivot_longer()
  • Convertir de format long en format large à l’aide de pivot_wider()
  • Séparer et regrouper des colonnes à l’aide de separate() et de son inverse, unite()

Voici un aide-mémoire (en anglais) pour faciliter la manipulation de jeux de données avec tidyr et dplyr: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf

Données en longueur vs. en largeur

Un jeu de données en largeur contient une colonne pour chaque variable ou facteur inclus dans les données. Une rangée peut alors comprendre plusieurs observations différentes.

Un jeu de données en longueur contient une colonne par variable, où chaque rangée s’agit d’une observation unique. Le format “long” est plus “propre” (tidy en anglais), parce que les données sont plus facilement interprétées par R pour nos visualisations et nos analyses.

Le format de vos données dépend de vos besoins d’analyse et de visualisation, mais certains paquets et fonctions, incluant dplyr, lm(), glm(), et gam(), nécessitent des données en longueur. Le paquet ggplot2 peut utiliser des données en largeur pour des visualisations simples, mais fonctionne mieux avec des données en longueur pour des visualisations plus complexes (exemple à venir).

De plus, les données en format long peuvent être agrégées et réorganisées en format large afin de produire des résumés ou de vérifier si un jeu de données est équilibré (i.e. avec le même nombre d’observations par traitement).

On peut utiliser le paquet tidyr pour manipuler la structure d’un jeu de données en préservant toutes les informations d’origine à l’aide des fonctions suivantes:

    1. “rassembler” les données (gather data en anglais; large --> long)
    1. “disperser” les données (spread data en anglais; long --> large)

Supposons que vous envoyez votre assistant de terrain pour faire la collecte de données des dimensions de plusieurs arbres sur un site de recherche, soit le diamètre à la hauteur de la poitrine (DHP) et la hauteur. Il/elle revient avec un jeu de données en format “dégât” (format large):

large <- data.frame(Species = c("Chêne", "Orme", "Frêne"),
                          DHP = c(12, 20, 13),
                         Haut = c(56, 85, 55))
large
##   Species DHP Haut
## 1   Chêne  12   56
## 2    Orme  20   85
## 3   Frêne  13   55

Utilisons la fonction pivot_longer() pour “rassembler” nos données en longueur. pivot_longer() prend plusieurs colonnes et les empile dans deux colonnes: une colonne spécifiant la variable mesurée, et l’autre spécifiant la mesure associée.

La fonction pivot_longer() prend au moins 3 arguments:

  • data: le jeu de données (e.g. “large”)
  • cols: les colonnes qu’on veut empiler dans le jeu de données (e.g. “DBH”, “Haut”)
  • names_to: le nom de la nouvelle colonne spécifiant la variable mesurée (e.g. “dimension”)
  • values_to: le nom de la nouvelle colonne spécifiant la mesure associée (e.g. “cm”)

Voici une démonstration avec le jeu de données large utilisé précédemment, contenant les dimensions d’arbres:

# Rassembler les colonnes en rangées d'observations uniques avec tidyr
library(tidyr)

pivot_longer(data      = large, 
                       cols      = c("DHP", "Haut"),
                       names_to  = "dimension", 
                       values_to = "cm")
## # A tibble: 6 × 3
##   Species dimension    cm
##   <chr>   <chr>     <dbl>
## 1 Chêne   DHP          12
## 2 Chêne   Haut         56
## 3 Orme    DHP          20
## 4 Orme    Haut         85
## 5 Frêne   DHP          13
## 6 Frêne   Haut         55

Réorganisez le jeu de données airquality en format long (en rassemblant toutes les colonnes sauf “Month” et “Day”).

Le jeu de données “airquality” est un data frame qui est déjà disponbible dans R:

data("airquality")
head(airquality)
##   Ozone Solar.R Wind Temp Month Day
## 1    41     190  7.4   67     5   1
## 2    36     118  8.0   72     5   2
## 3    12     149 12.6   74     5   3
## 4    18     313 11.5   62     5   4
## 5    NA      NA 14.3   56     5   5
## 6    28      NA 14.9   66     5   6

Le but est de rassembler les colonnes Ozone, Solar.R, Wind et Temp dans une seule colonne (“variable”) et leur données dans une autre colonne nommée “value”:

air.long <- pivot_longer(airquality,
                         cols = c("Ozone", "Solar.R", "Wind", "Temp"),
                         names_to = c("variable"),
                         values_to = c("value"))

head(air.long)
## # A tibble: 6 × 4
##   Month   Day variable value
##   <int> <int> <chr>    <dbl>
## 1     5     1 Ozone     41  
## 2     5     1 Solar.R  190  
## 3     5     1 Wind       7.4
## 4     5     1 Temp      67  
## 5     5     2 Ozone     36  
## 6     5     2 Solar.R  118

Utiliser “dplyr” pour manipuler les données

Souvent, on doit faire appel à une gamme d’outils complexes pour manipuler nos jeux de données. La mission de dplyr est de simplifier nos tâches de manipulation en regroupant toutes les opérations communes sous un même toit. Le résultat est une collection de fonctions ayant une syntaxe simple qu’on peut exécuter à l’aide de “verbes” (ou fonctions) intuitifs.

Au coeur du paquet dplyr, on retrouve des “verbes” essentiels qui nous permettent d’accomplir la manipulation de données. Voici 4 verbes qui exécutent les opérations les plus communes:

  • select() : sélectionne des colonnes dans un jeu de données
  • filter() : filtre des rangées suivant les critères spécifiés
  • arrange() : trie les données d’une colonne en ordre croissant ou décroissant
  • mutate() : crée une nouvelle colonne de données (ou transforme une colonne existante)

Ces opérations deviennent particulièrement puissants quand ils sont reliés par le “pipe” (%>%), et lorsqu’on les applique sur des sous-ensembles de données.

Supposons qu’on veut créer un sous-ensemble de airquality pour le mois de juin, et ensuite convertir la variable de la température en degrés Celsius. on peut écrire les opérations en ordre d’exécutions et les relier à l’aide du “pipe” %>% :

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
juin_C <- airquality %>%
    filter(Month == 6) %>%
    mutate(Temp_C = (Temp-32)*(5/9))

head(juin_C)
##   Ozone Solar.R Wind Temp Month Day   Temp_C
## 1    NA     286  8.6   78     6   1 25.55556
## 2    NA     287  9.7   74     6   2 23.33333
## 3    NA     242 16.1   67     6   3 19.44444
## 4    NA     186  9.2   84     6   4 28.88889
## 5    NA     220  8.6   85     6   5 29.44444
## 6    NA     264 14.3   79     6   6 26.11111

Regroupement d’opérations et sommaires avec “dplyr”

Les fonctions dplyr suivantes nous permettent de séparer nos jeu de données en groupes distincts sur lesquels on peut exécuter des opérations individuelles, comme des fonctions d’aggrégation et de sommaire:

  • group_by(): regrouper le jeu de données par un facteur pour les opérations en aval (comme summarise)
  • summarise(): créer un sommaire de variables au sein de groupes distincts dans un jeu de données en utilisant des fonctions d’aggrégation (e.g. min(), max(), mean(), etc…)

Ces deux verbes fournissent la structure requise pour la stratégie Séparer-Appliquer-Combiner (“Split-Apply-Combine”) originalement introduite dans le paquet plyr, l’ancêtre de dplyr.

Utilisons ces deux fonctions pour générer un sommaire du jeu de données airquality qui montre la température moyenne et l’écart type pour chaque mois:

> mois_moy <- airquality %>%
      group_by(Month) %>%
      summarise(mean_temp = mean(Temp),
                sd_temp = sd(Temp))
mois_moy
Source: local data frame [5 x 3]

  Month mean_temp  sd_temp
  (int)     (dbl)    (dbl)
1     5  65.54839 6.854870
2     6  79.10000 6.598589
3     7  83.90323 4.315513
4     8  83.96774 6.585256
5     9  76.90000 8.355671

Fusionner des tableaux de données avec dplyr

En plus des fonctions que nous avons explorées aujourd’hui, dplyr offre d’autres fonctions forts utiles nous permettant de fusionner des tableau de données, avec une syntaxe relativement simple :

  • left_join()
  • right_join()
  • inner_join()
  • anti_join()

Ces fonctions vont au-delà du matériel d’introduction dans cet atelier, mais ils offrent des fonctionnalités pouvant être très utiles pour des manipulations de données plus complexes. ————————————————————————

Pourquoi est-ce que c’est utile de manipuler les données comme ça?

Bref, pour les statistique et les visualisations! Voici, un example:

On veut visualiser le jeu de données airquality et on s’interesse à la variation des variables Ozone, Temp et Wind avec le temps. On sait déjà comment utiliser la fonction select() pour retenir uniquement les colonnes requises et on sait déjà comment rassembler les colonnes avec pivot_longer(). Cependant, pour le figure, les colonnes Month et Day seraient plus utiles dans un format de date. Donc, on peut faire toutes ces manipulations ensemble:

library(lubridate) # paquet pour transformer les dates!
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
air.plot <- airquality %>%
  select(c(Ozone, Temp, Wind, Month, Day)) %>%
  mutate(Date = lubridate::make_date("1973", Month, Day)) %>%
  pivot_longer(cols = c("Ozone", "Wind", "Temp"),
               names_to = c("variable"),
               values_to = c("value"))

Maintenant, on est capable de visualiser les données:

library(ggplot2)
ggplot(air.plot, 
       aes(x = Date, y = value, col = variable)) + 
  geom_point() + 
  geom_smooth()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

La visualisation des données avec ggplot2

Que voulez-vous communiquer? Quelle est la meilleure façon de représenter vos données et votre message?

De nombreux paquets R peuvent nous aider à créer des figures. Nous allons nous concentrer sur ggplot2 car: 1. ggplot2 vous permet de créer de beaux graphiques personnalisables;

2. ggplot2 implémente la grammaire des graphiques, qui est un système fiable pour construire des graphiques.

3. Il existe de nombreuses extensions pour ajouter encore plus de fonctionnalités à ggplot2, ce qui permet une multitude d’applications.

Quelques exemples:

Les bases de GG - la grammaire des graphiques (GG)

Commençons par les bases! La librairie ggplot2 est basée sur la Grammaire des Graphiques (GG), qui est un cadre pour la visualisation de données qui décompose chaque élément d’un graphique en composants individuels, créant ainsi des couches distinctes. En utilisant le système GG, nous pouvons construire des graphiques étape par étape pour des résultats flexibles et personnalisables.

Les couches GG ont des noms spécifiques que vous verrez tout au long de l’atelier:

Image adaptée de [The Grammar of Graphics](https://www.springer.com/gp/book/9780387245447).

Image adaptée de The Grammar of Graphics.

Pour créer un ggplot, les couches de données et de mapping sont des exigences de base, tandis que les autres couches sont destinées à une configuration supplémentaire. Les couches ‘non requises’ sont toujours importantes à considérer, mais vous serez en mesure de générer un graphique de base sans celles-ci.

Conditions de base pour générer un `ggplot'.

Conditions de base pour générer un `ggplot’.

Les couches de GG

Descriptions de couches courantes

Voici une décomposition de chaque couche Grammaire des Graphiques et des arguments courants pour chacune d’elles qui peut vous servir de référence:

  • Données :
    • vos données, dans un format tidy, fourniront les ingrédients de votre graphique.
    • utilisez les techniques dplyr pour préparer les données pour un format optimal pour la visualisation.
    • En général, cela signifie que vous devez avoir une rangée pour chaque observation que vous voulez visualiser.
  • Esthétique (aes), pour rendre les données visibles
    • x, y: position le long des axes x et y
    • colour: la couleur des géométries selon les données
    • fill: la couleur intérieure des géométries
    • group: à quel groupe appartient une géométrie
    • shape: la forme des points
    • linetype: le type de ligne utilisé (pleine, pointillée, etc.)
    • size: la taille des points ou des lignes
    • alpha: la transparence des géométries
  • Objets géométriques (geoms)
    • geom_point() : diagramme de dispersion
    • geom_line() : lignes reliant des points par une valeur croissante de x
    • geom_path() : lignes reliant des points dans l’ordre d’apparition
    • geom_boxplot() : diagramme en boîte (boxplot) pour les variables catégoriques
    • geom_bar() : diagrammes à barres pour un axe des x catégorique
    • geom_histogram() : histogramme pour l’axe des x continu
    • geom_violin() : kernel de distribution de la dispersion des données
    • geom_smooth() : ligne de lissage en fonction des données
  • Facettes
    • facet_wrap() ou facet_grid() pour de petits multiples
  • Statistiques
    • similaire aux géométries, mais issue de calcul sur les données
    • indique les moyennes, les comptages et autres résumés statistiques des données
  • Coordonnées - ajustement des données sur une page
    • coord_cartesian pour fixer des limites
    • coord_polar pour les graphiques circulaires
    • coord_map pour différentes projections cartographiques
  • Thèmes
    • Effets visuels globaux par défaut
    • polices, couleurs, formes, contours

Le jeu de données: palmerpenguins

Essayons maintenant de visualiser des données! Nous allons utiliser le jeu de données palmerpenguins.

Art par [Allison Horst](https://twitter.com/allison_horst).

Art par Allison Horst.

Ce jeu de données contient des mesures morphologiques pour trois espèces de pingouins observées sur trois îles de l’archipel Palmer, en Antarctique. Ces données ont été recueillies de 2007 à 2009 par la Dre Kristen Gorman dans le cadre du programme de recherche écologique à long terme de la station Palmer, qui fait partie du réseau américain de recherche écologique à long terme.

Artwork by [Allison Horst](https://twitter.com/allison_horst).

Artwork by Allison Horst.

Regardons les variables de l’ensemble de données des pingouins :

library(palmerpenguins)
data(penguins) # regardons les données des pingouins !
Art par [Allison Horst](https://twitter.com/allison_horst).

Art par Allison Horst.

Notez que l’espèce, l’île et le sexe (species, island, et sex) sont des facteurs, qui seront importantes pour regrouper les données avec des couleurs, des formes, etc. dans ggplot2. Il y a ensuite 2 variables numériques (mesures du bec représentées dans l’image), et deux variables entières (longueur des nageoires et masse corporelle). Les données ont également une petite composante temporelle (year), s’étendant de 2007 à 2009.

Notez: Les graphiques plus complexes dans les ggplot2 nécessitent que les données soient en format long.

Questions scientifiques à propos des pingouins

Quelles sont quelques questions scientifiques auxquelles nous pourrions vouloir répondre avec ce jeu de données? Voici quelques exemples:

  • Y a-t-il une relation entre la longueur et la profondeur des becs ?
  • Est-ce que la taille des becs et des nageoires varient ensemble ?
  • Comment ces mesures sont-elles réparties entre les 3 espèces ?

Comment pouvons-nous répondre graphiquement à ces questions avec ggplot2?

Explorer la structure des données

Nous devrions explorer comment certaines de ces données sont structurées par espèce!

# Explorons comment nos données sont structurées par espèce
ggplot(data = penguins,               # Données
       aes(x = bill_length_mm,        # Valeurs X
           y = bill_depth_mm,         # Valeurs Y
           col = species)) +          # Esthétique (mettre une couleur par espèce)
  geom_point(size = 5, alpha = 0.8) + # Points
  geom_smooth(method = "lm") +        # Régression linéaire
  labs(title = "Relationship between bill length and depth\nfor different penguin species", # Title
       x = "Bill length (mm)", # titre de l'axe des X
       y = "Bill depth (mm)", # titre de l'axe des Y
       col = "Species") +  # Légende pour les couleurs dans aes(col = species)
  theme_classic() + # Utiliser un thème propre
  theme(title = element_text(size = 18, face = "bold"),
      text = element_text(size = 16))

En différenciant les espèces, on peut voir qu’il existe une relation assez cohérente entre la longueur et la profondeur du bec entre les espèces (pentes similaires), mais que les gammes de ces variables sont différentes (les regroupements sont clairement indiqués par les couleurs). Les pingouins Adélie ont tendance à avoir une longueur de bec plus petite mais une profondeur de bec assez grande, alors que l’inverse est vrai pour les pingouins Gentoo.

La dynamique ggplot() par couches

Comme nous l’avons vu, un graphique est constitué de différentes couches, combinées ensemble pour communiquer visuellement des informations dans nos données. Construisons un graphique ggplot étape par étape en ajoutant une couche à la fois.

La couche de données

# Couche 1: Données
ggplot(data = penguins) 

# Sans autre information, vos données ne seront pas visualisées.

La couche d’esthétiques

Dans ggplot2, l’esthétique est un groupe de paramètres qui spécifie les données à afficher et la manière de les afficher. Ici, nous demandons à R de tracer longueur_de_bill_mm sur l’axe x et profondeur_de_bill_mm sur l’axe y. Nous n’avons pas encore dit à R comment nous voulons représenter les données, donc nos données ne seront pas encore tracées.

# Prochaine couche: esthétiques
# Ici, nous disons à R de tracer la longueur sur l'axe des x, et la profondeur sur l'axe des y.
# mais nous n'avons toujours pas dit à R comment nous voulons que ces données soient représentées...
ggplot(data = penguins, 
       aes(x = bill_length_mm, 
           y = bill_depth_mm)) 

# Vous voyez ? Nos variables sont maintenant assignées aux axes x et y, 
# mais rien n'est encore tracé.

La couche de géométries

Les objets géométriques, ou geoms, déterminent la représentation visuelle de vos données. Nous pouvons commencer par représenter nos points de données sous la forme d’un nuage de points, pour voir comment la profondeur et la longueur du bec sont liées l’une à l’autre.

# Prochaine couche(s): géométries
ggplot(data = penguins, 
       aes(x = bill_length_mm, 
           y = bill_depth_mm)) + # Utilisez le signe + pour ajouter chaque couche
  geom_point() # La couche geom détermine le type de tracé que nous utilisons.

               # geom_point() trace les données sous forme de points !

Notez que vous pouvez ajouter plusieurs geoms dans un seul graphique. Par exemple, nous pouvons ajouter une ligne sur ce graphique pour montrer une valeur seuil, ou ajouter une régression linéaire. Pour l’instant, gardons la simplicité!

Facettes, coordonnées, et thèmes

Maintenant que le jeu de données est représenté graphiquement, nous pouvons personnaliser le graphique pour clarifier le message ou ajouter des informations supplémentaires. Les facettes sont un moyen populaire de diviser un graphique en plusieurs fenêtres selon une catégorie de données, afin de différencier visuellement les groupes. Nous pouvons explorer ce graphique différemment si nous utilisons facet_wrap() pour créer des ‘facettes’ séparées en fonction de nos groupes d’espèces:

# Prochaine couche(s): customizations!
# Les facettes divisent un graphique en fenêtres séparées selon une certaine catégorie dans les données.
ggplot(data = penguins, 
       aes(x = bill_length_mm, 
           y = bill_depth_mm)) +
  geom_point() + 
  facet_wrap(vars(species)) # Cela divise le graphique en trois fenêtres : une par espèce.

Nous pouvons également ajuster l’échelle de nos axes dans le graphique lui-même, plutôt que de transformer les données. Supposons que nous souhaitions étudier la relation entre les mesures du bec sur une échelle de \(log_{10}\).

ggplot(data = penguins, 
       aes(x = bill_length_mm, 
           y = bill_depth_mm)) +
  geom_point() + 
  facet_wrap(vars(species)) +
  # ceci transforme les coordonnées des axes avec log10()
  coord_trans(x = "log10", y = "log10")

Pour terminer, nous pouvons également personnaliser le thème du graphique, qui comprend son arrière-plan, les quadrillages et d’autres caractéristiques visuelles du graphique. Supposons que nous n’aimons pas le fond gris par défaut de ggplot2 (nous ne serions pas les seuls!). Nous pouvons utiliser theme_bw() pour produire un rendu visuel plus attrayant. Nous discuterons des thèmes dans le chapitre @ref(theme)!

ggplot(data = penguins, 
       aes(x = bill_length_mm, 
           y = bill_depth_mm,
           col = species)) +
  geom_point() + 
  facet_wrap(vars(species)) +
  coord_trans(x = "log10", y = "log10") +
  # ce thème produit un rendu visuel plus attrayant
  theme_bw()

À vous!

Il est maintenant temps d’essayer de construire votre propre graphique ! Créez un ggplot pour répondre aux questions suivantes:

Équipe 1:

1. Y a-t-il une relation entre la longueur des becs et la longueur des nageoires des pingouins?

2. La longueur des becs augmente-t-elle avec celle des nageoires?

Paramètres à prendre en compte pour répondre à cette question:

données géométrie valeurs x valeurs y
penguins geom_point bill_length_mm flipper_length_mm

Équipe 2:

1. Y a-t-il une relation entre le sex et le poids corporelle?

2. Est-ce que la relation est pareil dans les trois especes?

Paramètres à prendre en compte pour répondre à cette question:

données géométrie valeurs x valeurs y
penguins geom_boxplot sex body_mass_g

Noubliez pas l’Esthétique (mettre une couleur par espèce), si utile!

Défi extra:

Essayez de manipuler le jeu de données penguins_raw.csv afin d’arriver au format de jeu de données penguins.csv. Les operations de tidyr et dplyr seraient utiles…

Obtenir de l’aide

Généralement, votre meilleure source d’information sera votre moteur de recherche préféré!

Voici quelques conseils pour l’utiliser efficacement:

  • Faites vos recherches en anglais
  • Utilisez le mot-clé R au début de votre recherche
  • Définissez précisément ce que vous recherchez
  • Apprenez à lire les forums de discussion, par exemple StackOverflow. Il est fort probable que d’autres personnes aient déjà eu le même problème que vous et aient posé la question à ce sujet.
  • N’hésitez pas à chercher à nouveau en utilisant différents mots-clés!

(N’oubliez pas l’ongle Help dans RStudio)